#include "Archivo.h"

Archivo::Archivo()
{
        this->nombreArchivo = "";
        this->mainFile = NULL;
        this->permiteEscritura = false;
        this->offSetArchivo = 0;
        this->lastRecordOffsetArchivo = 0;
};

Archivo::~Archivo()
{
};

void Archivo::setNombreArchivo(string value)
{
        this->nombreArchivo = value;
}

string Archivo::getNombreArchivo()
{
        return this->nombreArchivo;
}

bool Archivo::abrirArchivo(enum ModoApertura modoApertura)
{
        switch(modoApertura)
        {
                case maLectura:
                {
                        this->mainFile = fopen(this->nombreArchivo.c_str(), "rb");

                        if (this->mainFile != NULL)
                        {
                                this->permiteEscritura = false;

                                //me paro al final.
                                fseek(this->mainFile, 0, SEEK_END);
                                this->offSetArchivo = ftell(this->mainFile);
                                this->lastRecordOffsetArchivo = this->offSetArchivo;
                        }
                        break;
                }

                case maActualizacion:
                {
                        this->mainFile = fopen(this->nombreArchivo.c_str(), "rb+");

                        if (this->mainFile != NULL)
                        {
                                this->permiteEscritura = true;

                                //me paro al final.
                                fseek(this->mainFile, 0, SEEK_END);
                                this->offSetArchivo = ftell(this->mainFile);
                                this->lastRecordOffsetArchivo = this->offSetArchivo;
                        }
                        break;
                }

                case maEscrituraCreacion:
                {
                        this->mainFile = fopen(this->nombreArchivo.c_str(), "wb+");

                        if (this->mainFile != NULL)
                        {
                                this->permiteEscritura = true;
                        }

                        //me paro al principio.
                        this->offSetArchivo = 0;
                        this->lastRecordOffsetArchivo = 0;                        
                        break;
                }
        }

        if (this->mainFile != NULL)
        {
                return true;
        }

        return false;
}

bool Archivo::getAbierto()
{
        return (this->mainFile != NULL);
}

bool Archivo::getPermiteEscritura()
{
        return this->permiteEscritura;
}

bool Archivo::getEsFinDeArchivo()
{
        return (feof(this->mainFile) != 0);
}

long Archivo::getOffsetArchivo()
{
        return offSetArchivo;
}

long Archivo::getLastRecordOffsetArchivo()
{
        return lastRecordOffsetArchivo;
}

void Archivo::cerrarArchivo()
{
        if (this->mainFile != NULL)
        {
                fclose(this->mainFile);
        }
        
        this->mainFile = NULL;
        offSetArchivo = 0;
        lastRecordOffsetArchivo = 0;
}

bool Archivo::crearArchivo()
{
        return this->abrirArchivo(maEscrituraCreacion);
}

bool Archivo::escribirRegistro(Registro* registro)
{
        bool result = false;
        if ((this->getAbierto()) && (this->getPermiteEscritura()))
        {
                registro->fillBuffer();
                if ((registro->getBuffer() != NULL) && (registro->getTamanioBuffer() > 0))
                {
                        result =  (fwrite(registro->getBuffer(), registro->getTamanioBuffer(), 1, this->mainFile) == 1);
                        if (result)
                        {
                                lastRecordOffsetArchivo = offSetArchivo;
                                offSetArchivo += registro->getTamanioBuffer();
				fflush(this->mainFile);
                        }
                }
        }

        return result;
}

bool Archivo::leerRegistro(Registro* registro)
{
        bool result = false;
        
        if (this->getAbierto())
        {
                registro->crearBuffer();

                if ((registro->getBuffer() != NULL) &&
                    (registro->getTamanioBuffer() > 0))
                {
                        result = (fread(registro->getBuffer(), registro->getTamanioBuffer(), 1, this->mainFile) == 1);

                        if (result)
                        {
                                lastRecordOffsetArchivo = offSetArchivo;
                                offSetArchivo += registro->getTamanioBuffer();
                                registro->readFromBuffer();
                        }
                }
        }

        return result;
}

bool Archivo::posicionarEnArchivo(unsigned int offset)
{
        if (offSetArchivo != offset)
        {
                if (fseek(this->mainFile, offset, SEEK_SET) == 0)
                {
                        offSetArchivo = offset;
                        return true;
                }

                return false;
        }

        return true;
}

bool Archivo::posicionarAlFinal()
{
        if (fseek(this->mainFile, 0, SEEK_END) == 0)
        {
                this->offSetArchivo = ftell(this->mainFile);

                return true;
        }

        return false;
}

bool Archivo::ExisteDirectorio(const char* nombreDirectorio)
{
        #ifdef WIN32
        return (chdir(nombreDirectorio) == 0);
        #else
	return true;
        #endif
}

bool Archivo::CrearDirectorio(const char* nombreDirectorio)
{
        #ifdef WIN32
        return (mkdir(nombreDirectorio) == 0);
        #else
        return true;
        #endif
}

bool Archivo::RenombrarArchivo(const char* nombreAnterior, const char* nombreNuevo)
{
        return (rename(nombreAnterior, nombreNuevo) == 0);
}

bool Archivo::EliminarArchivo(const char* nombreArchivo)
{
        return (remove(nombreArchivo) == 0);
}

